#!/bin/bash

# ------------------------------------------------------------------
#  SSHFS 挂载管理工具 (后台守护进程版)
# 功能特性：
# 1. 基于配置文件的后台挂载/卸载
# 2. 唯一性PID文件管理
# 3. 多级卸载容错机制
# 4. 动态日志路径配置
# ------------------------------------------------------------------

CONFIG_FILE="$1"
ACTION="$2"

# -----------------------------------------------
# 日志记录函数
# 使用前需先加载配置确定LOG_FILE路径
# -----------------------------------------------
log() {
  echo "[$(date "+%Y-%m-%d %H:%M:%S")] $1" | tee -a "$LOG_FILE"
}

# -----------------------------------------------
# 挂载操作
# -----------------------------------------------
mount_fs() {
  source "$CONFIG_FILE"
  LOG_FILE="${LOG_FILE:-${HOME}/sshfs_mount.log}"
  
  local config_stem=$(basename "$CONFIG_FILE" | cut -d. -f1)
  local mount_name=$(basename "$LOCAL_MOUNT_POINT" | tr ' ' '_')
  PID_DIR="${HOME}/.sshfs_pids"
  PID_FILE="${PID_DIR}/${config_stem}_${mount_name}.pid"

  # 校验必需参数
  local required_params=("REMOTE_HOST" "REMOTE_DIR" "LOCAL_MOUNT_POINT")
  for param in "${required_params[@]}"; do
    if [[ -z "${!param}" ]]; then
      log "ERROR: 缺失必需参数 '$param'"
      exit 1
    fi
  done

  mkdir -p "$LOCAL_MOUNT_POINT" "$PID_DIR" || {
    log "ERROR: 目录创建失败 [$LOCAL_MOUNT_POINT 或 $PID_DIR]"
    exit 1
  }

  local remote_user_part="${REMOTE_USER:+${REMOTE_USER}@}"
  local remote_address="${remote_user_part}${REMOTE_HOST}:${REMOTE_DIR}"

  # 关键修改点：添加 uid 和 gid
  local sshfs_opts="volname=${VOLUME_NAME:-SSHFS_Volume},\
reconnect,\
follow_symlinks,\
allow_other,\
uid=$(id -u),\
gid=$(id -g),\
ServerAliveInterval=15,\
debug,\
sshfs_debug,\
loglevel=debug,\
${SSH_KEY:+IdentityFile=${SSH_KEY}}"

  log "INFO: 启动挂载进程 ▶ $remote_address → $LOCAL_MOUNT_POINT"
  nohup sshfs -p ${SSH_PORT:-22} -o "$sshfs_opts" "$remote_address" "$LOCAL_MOUNT_POINT" >> "$LOG_FILE" 2>&1 &
  local sshfs_pid=$!

  if ps -p $sshfs_pid > /dev/null; then
    echo $sshfs_pid > "$PID_FILE"
    log "SUCCESS: 进程已启动 PID:$sshfs_pid | PID文件: $PID_FILE"
    log "INFO: 挂载成功！检查日志: $LOG_FILE"
  else
    log "ERROR: 进程启动失败！检查日志: $LOG_FILE"
    exit 1
  fi
}

# -----------------------------------------------
# 卸载操作（含强制终止）
# -----------------------------------------------
unmount_fs() {
  # 加载配置文件
  source "$CONFIG_FILE"
  
  # 设置日志路径（与挂载时一致）
  LOG_FILE="${LOG_FILE:-${HOME}/sshfs_mount.log}"
  
  # 生成唯一PID文件名（必须与挂载时相同逻辑）
  local config_stem=$(basename "$CONFIG_FILE" | cut -d. -f1)
  local mount_name=$(basename "$LOCAL_MOUNT_POINT" | tr ' ' '_')
  PID_DIR="${HOME}/.sshfs_pids"
  PID_FILE="${PID_DIR}/${config_stem}_${mount_name}.pid"

  # 检查挂载状态
  if mount | grep -q "$LOCAL_MOUNT_POINT"; then
    log "INFO: 开始卸载操作 ▶ $LOCAL_MOUNT_POINT"

    # 第一阶段：正常卸载
    if diskutil unmount force "$LOCAL_MOUNT_POINT" >> "$LOG_FILE" 2>&1; then
      log "SUCCESS: 正常卸载完成"
      rm -f "$PID_FILE"
      return 0
    fi

    # 第二阶段：强制终止进程
    if [[ -f "$PID_FILE" ]]; then
      local sshfs_pid=$(cat "$PID_FILE")
      log "WARNING: 尝试终止进程 PID:$sshfs_pid"
      
      if kill -9 $sshfs_pid >> "$LOG_FILE" 2>&1; then
        log "INFO: 进程已终止，重新尝试卸载"
        rm -f "$PID_FILE"
        diskutil unmount force "$LOCAL_MOUNT_POINT" && return 0
      fi
    fi

    # 最终错误处理
    log "ERROR: 卸载失败！请手动检查："
    log "      1. 挂载点占用: lsof -V '$LOCAL_MOUNT_POINT'"
    log "      2. 进程状态: ps -p $sshfs_pid"
    log "      3. 网络连接: ssh -p ${SSH_PORT:-22} ${REMOTE_USER:-root}@$REMOTE_HOST"
    exit 1
  else
    log "WARN: 挂载点未激活 ▶ $LOCAL_MOUNT_POINT"
    rm -f "$PID_FILE"
  fi
}

# -----------------------------------------------
# 帮助信息
# -----------------------------------------------
usage() {
  cat <<EOF

██████████████████████████████████████████████
█          SSHFS 挂载管理工具 v2.0          █
██████████████████████████████████████████████

用法:
  $0 <配置文件> mount      启动后台挂载
  $0 <配置文件> unmount   安全卸载目录

配置文件示例 (~/.sshfs/example.cfg):
-----------------------------------
REMOTE_HOST="ip"
REMOTE_DIR="/data"
LOCAL_MOUNT_POINT="${HOME}/Volumes/aliyun"
REMOTE_USER="root"
SSH_KEY="~/.ssh/id_rsa"
VOLUME_NAME="aliyun"
LOG_FILE="/var/log/sshfs_custom.log"  # 可选

EOF
}

# -----------------------------------------------
# 主程序入口
# -----------------------------------------------
case "$ACTION" in
  mount)    mount_fs ;;
  unmount)  unmount_fs ;;
  *)        usage; exit 1 ;;
esac